﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CMN.Entity;
using CMN.Common;
using CMN.Framework;
using CMN.Config;
using CMN.BLL;
namespace CMN.UI
{

   /// <summary>
   /// 解析模板
   /// </summary>
    public class BaseTemplateDisplay:IDisposable
    {
        #region 定义变量

        static BaseTemplateDisplay()
        {
            try
            {
                List<TemplateDisplayInfo> configs = TemplateDisplayConfigs.GetTemplateConfig().TemplateDisplayInfos;
                foreach (TemplateDisplayInfo info in configs)
                {
                    try
                    {
                        var t = Type.GetType(info.NameSpace);
                        System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(t.TypeHandle);
                    }
                    catch (Exception ex)
                    {
                        AppLog.Write("初始化模板解析类错误" + info.NameSpace, AppLog.LogMessageType.Error, ex);
                    }
                }

            }
            catch (Exception ex)
            {
                AppLog.Write("初始化模板解析类错误", AppLog.LogMessageType.Error, ex);
            }

            //获取Type，不引发静态构造函数运行
            //var t = Type.GetType("CME.UI.Normal_NoticeDisplay");
            // System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(t.TypeHandle);
        }
        /// <summary>
        /// 页面信息
        /// </summary>
        public PageHelperEntity pageHelperEntity = null;

        /// <summary>
        /// 模板
        /// </summary>
        public Normal_TemplatesEntity templateEntity = null;
        /// <summary>
        /// 模板详细信息
        /// </summary>
        public Normal_TemplateListEntity templateeListEntity = null;
        /// <summary>
        /// 模板皮肤
        /// </summary>
        public Normal_SkinEntity skinEntity = null;
        /// <summary>
        /// 模板帮助类
        /// </summary>
        protected NVelocityHelper nvelocity = null;

        protected Normal_ChannelEntity channelEntity = null;
        protected TemplateDisplay tDisplay = null;
        /// <summary>
        /// 是否解析
        /// </summary>
        protected bool isStop = false;
        #endregion

        #region  定义事件
        /// <summary>
        /// 基类绑定前触发事件
        /// </summary>
        public static event EventHandler<TemplateArg> OnNVelocityLoadPath;

        /// <summary>
        /// 基类绑定前触发事件
        /// </summary>
        public static event EventHandler<TemplateDisplayArg> OnBeforeBaseDisplay;

        /// <summary>
        /// 基类绑定后触发事件
        /// </summary>
        public static event EventHandler<TemplateDisplayArg> OnAfterBaseDisplay;

        /// <summary>
        /// 所有绑定后触发事件
        /// </summary>
        public static event EventHandler<TemplateDisplayArg> OnEndDisplay;
        /// <summary>
        /// 首页展示解析前事件
        /// </summary>
        public static event EventHandler<TemplateDisplayArg> OnIndexPageDisplay;

        /// <summary>
        /// 封面展示解析前事件
        /// </summary>
        public static event EventHandler<TemplateDisplayArg> OnChannelsPageDisplay;

        /// <summary>
        /// 列表解析前事件
        /// </summary>
        public static event EventHandler<TemplateDisplayArg> OnChannelPageDisplay;

        /// <summary>
        /// 详细内容解析前事件
        /// </summary>
        public static event EventHandler<TemplateDisplayArg> OnContentPageDisplay;
        /// <summary>
        /// 解析文章前触发事件
        /// </summary>
        public static event EventHandler<ArticleDisplayArg> OnArticlePageDisplay;

        /// <summary>
        /// 搜索页面解析前事件
        /// </summary>
        public static event EventHandler<TemplateDisplayArg> OnSearchPageDisplay;

        /// <summary>
        /// 其他页面解析前事件
        /// </summary>
        public static event EventHandler<TemplateDisplayArg> OnOtherPageDisplay;
        #endregion

        /// <summary>
        /// 初始化模板 
        /// </summary>
        /// <param name="channelId">频道Id  0为默认</param>
        public BaseTemplateDisplay(PageHelperEntity tHelper)
        {
            this.pageHelperEntity = tHelper;
            channelEntity = pageHelperEntity.Channel;
            if (tHelper.TType == TemplateType.Phone)
            {
                templateEntity = MvcWebCacheManager.GetTemlateEntity("templates\\wap");
            }
            else
            {
                switch (pageHelperEntity.Type)
                {
                    case PageType.IndexPage:
                        {
                            templateEntity = MvcWebCacheManager.GetDefaultTemlateEntity();
                            break;
                        }
                    case PageType.ChannelsPage:
                        {
                           
                            if (channelEntity == null)
                            {
                                templateEntity = MvcWebCacheManager.GetDefaultTemlateEntity();
                            }
                            else
                            {
                                if (channelEntity.TemplateId == 0)
                                {
                                    templateEntity = MvcWebCacheManager.GetDefaultTemlateEntity();
                                }
                                else
                                {
                                    templateeListEntity = MvcWebCacheManager.GetTemlateListEntity(channelEntity.TemplateId);
                                    templateEntity = MvcWebCacheManager.GetTemlateEntity(templateeListEntity.TemplateId);
                                }
                               
                            }
                            break;

                        }
                    case PageType.ChannelPage:
                        {
                           
                            if (channelEntity == null)
                            {
                                templateEntity = MvcWebCacheManager.GetDefaultTemlateEntity();
                            }
                            else
                            {
                                if (channelEntity.TemplateId == 0)
                                {
                                    templateEntity = MvcWebCacheManager.GetDefaultTemlateEntity();
                                }
                                else
                                {
                                    templateeListEntity = MvcWebCacheManager.GetTemlateListEntity(channelEntity.TemplateId);
                                    templateEntity = MvcWebCacheManager.GetTemlateEntity(templateeListEntity.TemplateId);
                                }
                                
                            }

                            break;
                        }
                    case PageType.ContentPage:
                        {
                            channelEntity = pageHelperEntity.Channel;
                            if (channelEntity == null)
                            {
                                templateEntity = MvcWebCacheManager.GetDefaultTemlateEntity();
                            }
                            else
                            {
                                if (channelEntity.ContentTemplateId == 0)
                                {
                                    templateEntity = MvcWebCacheManager.GetDefaultTemlateEntity();
                                }
                                else
                                {
                                    templateeListEntity = MvcWebCacheManager.GetTemlateListEntity(channelEntity.ContentTemplateId);
                                    templateEntity = MvcWebCacheManager.GetTemlateEntity(templateeListEntity.TemplateId);
                                }
                                
                            }
                            break;
                        }
                    case PageType.OtherPage:
                        {
                            //加载只定义模板路径
                            if (OnNVelocityLoadPath != null)
                            {
                                
                                TemplateArg tArg = new TemplateArg(this.pageHelperEntity, this.templateEntity);
                               
                                OnNVelocityLoadPath(EventArgs.Empty, tArg);
                               // AppLog.Write("OnNVelocityLoadPath" , AppLog.LogMessageType.Error);
                                this.pageHelperEntity = tArg.PageHelper;
                                this.templateEntity = tArg.TemplateEntity;
                            }

                            break;
                        }
                    default:
                        {
                            templateEntity = MvcWebCacheManager.GetDefaultTemlateEntity();
                            break;
                        }
                }
            }
           
            if (templateEntity == null)
            {
                throw new Exception("模板初始化错误 模板为空");
            }
            if (templateEntity == null)
            {
                Utils.Redirect404();
                return;
            }
            skinEntity = MvcWebCacheManager.GetSkinEntity(templateEntity.SkinID);
            skinEntity.TemplateName = templateEntity.DirName;
            
            nvelocity = new NVelocityHelper(string.Concat(Utils.GetServerPath(),"templates"),true,SiteConfigs.GetSiteConfig().IsCacheTemplate);
            //nvelocity.SetLoaderCache(true, 3600);
            //绑定前触发事件
            if (OnBeforeBaseDisplay != null)
                OnBeforeBaseDisplay(EventArgs.Empty, new TemplateDisplayArg(pageHelperEntity, nvelocity));
            baseDisplay();
            //绑定后触发事件
            if (OnAfterBaseDisplay != null)
                OnAfterBaseDisplay(EventArgs.Empty, new TemplateDisplayArg(pageHelperEntity, nvelocity));
         
            if (pageHelperEntity.Type == PageType.ContentPage)
            {
               
                if (!GetContent())
                {
                    isStop = true;
                }
            }
            if (OnEndDisplay != null)
                OnEndDisplay(EventArgs.Empty, new TemplateDisplayArg(pageHelperEntity, nvelocity));

        }

        private void baseDisplay()
        {

            nvelocity.Put("site", SiteConfigs.GetSiteConfig());
            nvelocity.Put("skin", skinEntity);
            nvelocity.Put("page", pageHelperEntity);
             tDisplay = new TemplateDisplay();
            nvelocity.Put("cmn", tDisplay);

        }


        /// <summary>
        /// 获取详细内容
        /// </summary>
        private bool GetContent()
        {
            switch (channelEntity.ChannelType)
            {
                case "Article":
                    {
                       
                        Module_Article bllArticle = new Module_Article();
                        Module_ArticleEntity article = bllArticle.Disp(pageHelperEntity.ContentId, pageHelperEntity.PageIndex, SiteConfigs.GetSiteConfig().PagingNum);
                        
                        if (article == null)
                        {
                            Utils.Redirect404();
                            return false;
                        }
                        if (OnArticlePageDisplay != null)
                        {
                            OnArticlePageDisplay(EventArgs.Empty, new ArticleDisplayArg(this.pageHelperEntity, this.nvelocity, article));
                        }
                        
                        nvelocity.Put("article", article);
                        
                        break;
                    }
                case "Soft":
                    {
                        Module_Soft soft = new Module_Soft();
                        Module_SoftEntity article = soft.Disp(pageHelperEntity.ContentId);
                        if (article == null)
                        {
                            Utils.Redirect404();
                            return false;
                        }
                        nvelocity.Put("soft", article);
                        break;
                    }
                case "Photo":
                    {
                        Module_Photo photo = new Module_Photo();
                        Module_PhotoEntity article = photo.Disp(pageHelperEntity.ContentId);
                        if (article == null)
                        {
                            Utils.Redirect404();
                            return false;
                        }
                        nvelocity.Put("photo", article);
                        break;
                    }
                case "Video":
                    {
                        Module_Video video = new Module_Video();
                        Module_VideoEntity article = video.Disp(pageHelperEntity.ContentId);
                        if (article == null)
                        {
                            Utils.Redirect404();
                            return false;
                        }
                        nvelocity.Put("video", article);
                        break;
                    }
            }
            return true;
        }

        /// <summary>
        /// 解析
        /// </summary>
        /// <returns></returns>
        public string Display()
        {
            if (!isStop)
            {

                switch (pageHelperEntity.Type)
                {
                    case PageType.IndexPage:
                        {

                            if (OnIndexPageDisplay != null)
                                OnIndexPageDisplay(EventArgs.Empty, new TemplateDisplayArg(pageHelperEntity, nvelocity));
                            return nvelocity.Display(string.Concat(skinEntity.TemplateName, "\\default.htm")).ToString();
                        }
                    case PageType.ChannelsPage:
                        {
                            GetNavigator();
                            if (OnChannelsPageDisplay != null)
                                OnChannelsPageDisplay(EventArgs.Empty, new TemplateDisplayArg(pageHelperEntity, nvelocity));
                            if (templateeListEntity == null)
                                return nvelocity.Display(string.Concat(skinEntity.TemplateName, "\\", channelEntity.ChannelType, "Channels.htm")).ToString();
                            else
                                return nvelocity.Display(string.Concat(skinEntity.TemplateName, "\\", templateeListEntity.TemplateName)).ToString();


                        }
                    case PageType.ChannelPage:
                        {
                            GetNavigator();
                            if (OnChannelPageDisplay != null)
                                OnChannelPageDisplay(EventArgs.Empty, new TemplateDisplayArg(pageHelperEntity, nvelocity));
                            if (templateeListEntity == null)
                                return nvelocity.Display(string.Concat(skinEntity.TemplateName, "\\", channelEntity.ChannelType, "Channel.htm")).ToString();
                            else
                                return nvelocity.Display(string.Concat(skinEntity.TemplateName, "\\", templateeListEntity.TemplateName)).ToString();


                        }
                    case PageType.ContentPage:
                        {
                            GetNavigator();
                            if (OnContentPageDisplay != null)
                                OnContentPageDisplay(EventArgs.Empty, new TemplateDisplayArg(pageHelperEntity, nvelocity));
                            if (templateeListEntity == null)
                                return nvelocity.Display(string.Concat(skinEntity.TemplateName, "\\", channelEntity.ChannelType, "content.htm")).ToString();
                            else
                                return nvelocity.Display(string.Concat(skinEntity.TemplateName, "\\", templateeListEntity.TemplateName)).ToString();


                        }
                    case PageType.SearchPage:
                        {
                            if (OnSearchPageDisplay != null)
                                OnSearchPageDisplay(EventArgs.Empty, new TemplateDisplayArg(pageHelperEntity, nvelocity));

                            return nvelocity.Display(string.Concat(skinEntity.TemplateName, "\\", "search.htm")).ToString();
                        }
                    case PageType.OtherPage:
                        {
                            if (OnOtherPageDisplay != null)
                                OnOtherPageDisplay(EventArgs.Empty, new TemplateDisplayArg(pageHelperEntity, nvelocity));
                            if (string.IsNullOrEmpty(templateEntity.TemplateName))
                            {
                                throw new Exception("TemplateName 不能为空");
                            }
                            return nvelocity.Display(string.Concat(skinEntity.TemplateName, "\\", templateEntity.TemplateName)).ToString();
                        }

                    default:
                        {
                            throw new Exception("错误的模板类型", null);
                        }
                }
            }
            else
                return "";

        }

        /// <summary>
        /// 解析页面
        /// </summary>
        /// <param name="templateName"></param>
        /// <returns></returns>
        public string Display(string templateName)
        {
            if (!isStop)
                return nvelocity.Display(string.Concat(skinEntity.TemplateName, "\\", templateName)).ToString();
            else
                return "";
        }


        /// <summary>
        /// 获取导航栏目列表
        /// </summary>
        private void GetNavigator()
        {

            if (pageHelperEntity.Channel != null && pageHelperEntity.Channel.ReId != 0)
            {
                List<Normal_ChannelEntity> channelList = new List<Normal_ChannelEntity>();
                List<Normal_ChannelEntity> navigatorChannelList = new List<Normal_ChannelEntity>();
                List<Normal_ChannelEntity> rrChannelList = new List<Normal_ChannelEntity>();

                channelList = MvcWebCacheManager.GetNormal_ChannelList();
                GetParentChannel(navigatorChannelList, channelList, pageHelperEntity.Channel.ReId);
                for (int i = (navigatorChannelList.Count - 1); i >= 0; i--)
                {
                    rrChannelList.Add(navigatorChannelList[i]);
                }

                pageHelperEntity.Navigator = rrChannelList;
            }
        }

        /// <summary>
        /// 循环获取父级栏目
        /// </summary>
        /// <param name="rchannelList">返回的父级栏目列表</param>
        /// <param name="channelList">所有栏目列表</param>
        /// <param name="parentChannelId">当前栏目父级Id</param>
        private void GetParentChannel(List<Normal_ChannelEntity> rchannelList, List<Normal_ChannelEntity> channelList, int parentChannelId)
        {
            foreach (Normal_ChannelEntity channel in channelList)
            {
                if (channel.Id == parentChannelId)
                {
                    rchannelList.Add(channel);
                    GetParentChannel(rchannelList, channelList, channel.ReId);
                    break;
                }
            }
        }

        /// <summary>
        /// 释放
        /// </summary>
        public void Dispose()
        {
            channelEntity = null;
          
            pageHelperEntity = null;
            templateEntity = null;
            skinEntity = null;
            tDisplay = null;
            nvelocity.Dispose();
            nvelocity = null;
           
        }




    }

   
}